import { PublicClientApplication, AuthenticationResult, AccountInfo } from '@azure/msal-browser';
import { msalConfig, loginRequest, loginRequestWithFormPost, logoutRequest } from '@/config/msal-config';

class MsalService {
  private msalInstance: PublicClientApplication | null = null;
  private account: AccountInfo | null = null;

  constructor() {
    console.log('🔧 MSAL服务初始化开始');
    this.initializeMsal();
  }

  private async initializeMsal() {
    try {
      console.log('🔧 创建MSAL实例...');
      this.msalInstance = new PublicClientApplication(msalConfig);
      
      console.log('🔧 初始化MSAL实例...');
      await this.msalInstance.initialize();
      console.log('✅ MSAL实例初始化成功');
      
      // 处理重定向响应
      console.log('🔧 检查是否有重定向响应需要处理...');
      console.log('🔧 当前URL:', window.location.href);
      console.log('🔧 URL包含fragment:', window.location.hash ? '是' : '否');
      
      const response = await this.msalInstance.handleRedirectPromise();
      if (response) {
        console.log('✅ 检测到重定向响应:', {
          account: response.account?.username,
          accessToken: response.accessToken ? '已获取' : '未获取',
          expiresOn: response.expiresOn,
          scopes: response.scopes,
          tokenType: response.tokenType
        });
        this.account = response.account;
        return response;
      } else {
        console.log('ℹ️ 没有检测到重定向响应');
        
        // 检查URL中是否有fragment参数
        if (window.location.hash) {
          console.log('⚠️ 检测到URL fragment，但MSAL未处理');
          console.log('🔍 Fragment内容:', window.location.hash);
          
          // 尝试手动解析fragment
          const fragmentParams = this.parseFragment(window.location.hash);
          console.log('🔍 解析的fragment参数:', fragmentParams);
          
          if (fragmentParams.access_token) {
            console.log('✅ 在fragment中检测到access_token');
            // 这里可以手动处理token
          }
        }
      }
      
      // 检查是否有活跃账户
      console.log('🔧 检查活跃账户...');
      const accounts = this.msalInstance.getAllAccounts();
      console.log(`ℹ️ 找到 ${accounts.length} 个账户`);
      if (accounts.length > 0) {
        this.account = accounts[0];
        console.log('✅ 设置活跃账户:', this.account.username);
      }
    } catch (error) {
      console.error('❌ MSAL初始化失败:', error);
      // 如果是400错误，可能是配置问题
      if (error instanceof Error && error.message.includes('400')) {
        console.error('❌ 检测到400错误，请检查以下配置:');
        console.error('1. 客户端ID是否正确');
        console.error('2. 租户ID是否正确');
        console.error('3. 重定向URI是否在Azure AD中正确配置');
        console.error('4. 应用权限是否正确设置');
      }
    }
  }

  // 解析URL fragment参数
  private parseFragment(fragment: string): Record<string, string> {
    const params: Record<string, string> = {};
    if (fragment.startsWith('#')) {
      fragment = fragment.substring(1);
    }
    
    const pairs = fragment.split('&');
    for (const pair of pairs) {
      const [key, value] = pair.split('=');
      if (key && value) {
        params[decodeURIComponent(key)] = decodeURIComponent(value);
      }
    }
    
    return params;
  }

  // 手动构建包含form_post响应模式的授权URL
  public buildAuthUrlWithFormPost(): string {
    const clientId = msalConfig.auth.clientId;
    const tenantId = 'afebf5f7-d49a-419a-8d2c-5d08baabdee1'; // 直接使用租户ID
    const redirectUri = encodeURIComponent(msalConfig.auth.redirectUri || '');
    const scopes = encodeURIComponent(loginRequestWithFormPost.scopes.join(' '));
    const state = this.generateState();
    const nonce = this.generateNonce();
    
    console.log('🔧 构建form_post URL参数:');
    console.log('- 客户端ID:', clientId);
    console.log('- 租户ID:', tenantId);
    console.log('- 重定向URI:', msalConfig.auth.redirectUri);
    console.log('- Scope:', loginRequestWithFormPost.scopes);
    console.log('- State:', state);
    console.log('- Nonce:', nonce);
    
    const authUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize?` +
      `client_id=${clientId}&` +
      `scope=${scopes}&` +
      `redirect_uri=${redirectUri}&` +
      `response_type=code&` +
      `response_mode=form_post&` +
      `state=${state}&` +
      `nonce=${nonce}&` +
      `prompt=login&` +
      `client_info=1`;
    
    console.log('🔧 生成的完整URL:', authUrl);
    console.log('🔧 URL包含response_mode=form_post:', authUrl.includes('response_mode=form_post'));
    
    return authUrl;
  }

  // 生成state参数
  private generateState(): string {
    return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
  }

  // 生成nonce参数
  private generateNonce(): string {
    return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
  }

  async login(): Promise<AuthenticationResult | null> {
    if (!this.msalInstance) {
      console.error('❌ MSAL实例未初始化');
      return null;
    }

    try {
      console.log('🔧 开始MS365登录流程...');
      console.log('🔧 重定向URI:', msalConfig.auth.redirectUri);
      console.log('🔧 客户端ID:', msalConfig.auth.clientId);
      console.log('🔧 Scope配置:', loginRequestWithFormPost.scopes);
      console.log('🔧 响应模式:', loginRequestWithFormPost.responseMode);
      
      // 直接使用手动构建的URL，确保response_mode=form_post
      console.log('🔧 使用手动构建的form_post URL...');
      const authUrl = this.buildAuthUrlWithFormPost();
      console.log('🔧 手动构建的授权URL:', authUrl);
      
      // 验证URL是否包含form_post
      if (!authUrl.includes('response_mode=form_post')) {
        console.error('❌ 生成的URL不包含form_post模式');
        throw new Error('URL构建失败：缺少form_post响应模式');
      }
      
      console.log('✅ URL验证通过，包含form_post模式');
      window.location.href = authUrl;
      console.log('✅ 登录重定向已触发（使用form_post模式）');
      return null; // 重定向后不会返回结果
    } catch (error) {
      console.error('❌ 登录失败:', error);
      // 详细错误信息
      if (error instanceof Error) {
        console.error('❌ 错误详情:', {
          message: error.message,
          name: error.name,
          stack: error.stack
        });
      }
      throw error;
    }
  }

  async logout(): Promise<void> {
    if (!this.msalInstance) {
      console.error('❌ MSAL实例未初始化');
      return;
    }

    try {
      console.log('🔧 开始登出流程...');
      await this.msalInstance.logoutPopup(logoutRequest);
      this.account = null;
      console.log('✅ 登出成功');
    } catch (error) {
      console.error('❌ 登出失败:', error);
      throw error;
    }
  }

  async acquireToken(): Promise<string | null> {
    if (!this.msalInstance) {
      console.error('❌ MSAL实例未初始化');
      return null;
    }

    if (!this.account) {
      console.error('❌ 没有活跃账户');
      return null;
    }

    try {
      console.log('🔧 尝试静默获取访问令牌...');
      console.log('🔧 账户信息:', {
        username: this.account.username,
        homeAccountId: this.account.homeAccountId
      });
      
      const response = await this.msalInstance.acquireTokenSilent({
        ...loginRequestWithFormPost,
        account: this.account,
      });
      console.log('✅ 静默获取令牌成功');
      return response.accessToken;
    } catch (error) {
      console.error('❌ 静默获取令牌失败:', error);
      
      // 如果是400错误，提供详细的诊断信息
      if (error instanceof Error && error.message.includes('400')) {
        console.error('❌ 400错误诊断信息:');
        console.error('- 检查Azure AD应用注册中的重定向URI配置');
        console.error('- 检查应用权限是否正确授予');
        console.error('- 检查客户端密钥是否有效');
        console.error('- 检查租户ID是否正确');
      }
      
      // 如果静默获取失败，尝试交互式获取
      try {
        console.log('🔧 尝试交互式获取访问令牌...');
        const response = await this.msalInstance.acquireTokenPopup(loginRequestWithFormPost);
        console.log('✅ 交互式获取令牌成功');
        return response.accessToken;
      } catch (popupError) {
        console.error('❌ 交互式获取令牌失败:', popupError);
        
        // 如果是400错误，提供更详细的错误信息
        if (popupError instanceof Error && popupError.message.includes('400')) {
          console.error('❌ 交互式获取400错误详情:');
          console.error('- 错误消息:', popupError.message);
          console.error('- 请检查Azure AD应用配置');
        }
        
        throw popupError;
      }
    }
  }

  // 使用授权码通过后端API获取令牌和用户信息
  async acquireTokenByCode(code: string, state?: string, forceGraphFetch: boolean = false): Promise<AuthenticationResult | null> {
    if (!this.msalInstance) {
      console.error('❌ MSAL实例未初始化');
      return null;
    }

    try {
      console.log('🔧 使用授权码通过后端API获取令牌和用户信息...');
      console.log('🔑 授权码:', code.substring(0, 20) + '...');
      console.log('🔑 State:', state);
      
      // 获取Azure AD配置
      const clientId = import.meta.env.VITE_MS_365_CLIENT_ID;
      const tenantId = import.meta.env.VITE_MS_365_TENANT_ID;
      
      if (!clientId || !tenantId) {
        throw new Error('缺少MS365配置：请检查VITE_MS_365_CLIENT_ID和VITE_MS_365_TENANT_ID');
      }
      
      console.log('🔧 调用后端API进行令牌交换...');
      
      // 调用后端API进行令牌交换
      const apiUrl = `${import.meta.env.VITE_API_BASE_URL}/api/auth/exchange-code`;
      const requestData = {
        code: code,
        scopes: loginRequestWithFormPost.scopes,
        redirectUri: msalConfig.auth.redirectUri || ''
      };
      
      console.log('🔧 API请求URL:', apiUrl);
      console.log('🔧 API请求数据:', {
        code: code.substring(0, 20) + '...',
        scopes: loginRequestWithFormPost.scopes,
        redirectUri: msalConfig.auth.redirectUri
      });
      
      const response = await fetch(apiUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(requestData)
      });
      
      const responseText = await response.text();
      console.log('📋 后端API响应状态:', response.status);
      console.log('📋 后端API响应内容:', responseText);
      
      if (!response.ok) {
        console.error('❌ 后端API调用失败:', response.status, responseText);
        throw new Error(`后端API调用失败 (${response.status}): ${responseText}`);
      }
      
      const tokenResponse = JSON.parse(responseText);
      console.log('✅ 后端API调用成功');
      
      // 获取用户信息
      const userInfo = await this.getUserInfoFromGraph(tokenResponse.access_token);
      
      // 如果没有获取到用户信息，创建一个默认的账户信息
      const defaultAccount: AccountInfo = {
        homeAccountId: '',
        environment: 'login.microsoftonline.com',
        tenantId: tenantId || '',
        username: '',
        name: '',
        localAccountId: ''
      };
      
      // 构造MSAL兼容的响应格式
      const msalResponse: AuthenticationResult = {
        accessToken: tokenResponse.access_token,
        tokenType: tokenResponse.token_type,
        expiresOn: new Date(Date.now() + tokenResponse.expires_in * 1000),
        scopes: tokenResponse.scope ? tokenResponse.scope.split(' ') : [],
        account: userInfo || defaultAccount,
        authority: msalConfig.auth.authority || `https://login.microsoftonline.com/${tenantId}`,
        uniqueId: userInfo?.homeAccountId || '',
        tenantId: tenantId || '',
        idToken: tokenResponse.id_token,
        idTokenClaims: tokenResponse.id_token ? this.parseJwt(tokenResponse.id_token) : undefined,
        correlationId: state || '',
        fromCache: false,
        state: state || ''
      };
      
      // 更新账户信息
      if (userInfo) {
        this.account = userInfo;
      }
      
      console.log('✅ 成功获取令牌和用户信息:', {
        username: msalResponse.account?.username,
        name: msalResponse.account?.name,
        accessToken: msalResponse.accessToken ? '已获取' : '未获取',
        expiresOn: msalResponse.expiresOn,
        scopes: msalResponse.scopes
      });
      
      return msalResponse;
    } catch (error) {
      console.error('❌ 使用授权码获取令牌失败:', error);
      
      // 如果是400错误，提供详细的诊断信息
      if (error instanceof Error && error.message.includes('400')) {
        console.error('❌ 400错误诊断信息:');
        console.error('- 检查Azure AD应用注册中的重定向URI配置');
        console.error('- 检查应用权限是否正确授予');
        console.error('- 检查客户端密钥是否有效');
        console.error('- 检查租户ID是否正确');
        console.error('- 检查授权码是否有效');
      }
      
      // 如果是客户端密钥相关错误
      if (error instanceof Error && error.message.includes('MS365_CLIENT_SECRET')) {
        console.error('❌ 客户端密钥配置错误:');
        console.error('- 请在.env文件中配置VITE_MS_365_CLIENT_SECRET');
        console.error('- 或者在后端处理授权码交换');
      }
      
      throw error;
    }
  }

  // 从Microsoft Graph获取用户信息
  public async getUserInfoFromGraph(accessToken: string): Promise<AccountInfo | null> {
    try {
      console.log('🔍 从Microsoft Graph获取用户信息...');
      
      const response = await fetch('https://graph.microsoft.com/v1.0/me', {
        headers: {
          'Authorization': `Bearer ${accessToken}`,
          'Content-Type': 'application/json'
        }
      });
      
      if (!response.ok) {
        console.error('❌ 获取用户信息失败:', response.status, response.statusText);
        return null;
      }
      
      const userData = await response.json();
      console.log('📋 用户数据:', userData);
      
      // 构造AccountInfo对象
      const accountInfo: AccountInfo = {
        homeAccountId: userData.id || '',
        environment: 'login.microsoftonline.com',
        tenantId: userData.id?.split('.')[0] || '',
        username: userData.userPrincipalName || userData.mail || '',
        name: userData.displayName || userData.userPrincipalName || '',
        localAccountId: userData.id || ''
      };
      
      console.log('✅ 成功获取用户信息:', accountInfo);
      return accountInfo;
    } catch (error) {
      console.error('❌ 获取用户信息失败:', error);
      return null;
    }
  }

  // 解析JWT令牌
  private parseJwt(token: string): any {
    try {
      const base64Url = token.split('.')[1];
      const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
      const jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
      }).join(''));
      return JSON.parse(jsonPayload);
    } catch (error) {
      console.error('❌ 解析JWT失败:', error);
      return null;
    }
  }

  // 获取当前用户信息
  getUserInfo(): { username: string; name: string } | null {
    if (!this.account) {
      return null;
    }
    
    return {
      username: this.account.username,
      name: this.account.name || this.account.username
    };
  }

  getAccount(): AccountInfo | null {
    return this.account;
  }

  isAuthenticated(): boolean {
    return this.account !== null;
  }

  // 添加诊断方法
  async diagnoseConfiguration() {
    console.log('🔍 MSAL配置诊断:');
    console.log('- 客户端ID:', msalConfig.auth.clientId);
    console.log('- 租户ID:', msalConfig.auth.authority);
    console.log('- 重定向URI:', msalConfig.auth.redirectUri);
    console.log('- Scope配置:', loginRequestWithFormPost.scopes);
    console.log('- 响应模式:', loginRequestWithFormPost.responseMode);
    
    if (!this.msalInstance) {
      console.error('❌ MSAL实例未初始化');
      return;
    }
    
    const accounts = this.msalInstance.getAllAccounts();
    console.log('- 活跃账户数量:', accounts.length);
    
    if (accounts.length > 0) {
      console.log('- 第一个账户:', accounts[0].username);
    }
    
    // 检查当前URL
    console.log('- 当前URL:', window.location.href);
    console.log('- URL包含fragment:', window.location.hash ? '是' : '否');
    
    if (window.location.hash) {
      const fragmentParams = this.parseFragment(window.location.hash);
      console.log('- Fragment参数:', fragmentParams);
    }
  }
}

// 创建单例实例
export const msalService = new MsalService();
export default msalService; 